import unittest

import fitz

from tests.base_test import base_test_case

logger = base_test_case.get_logger(__name__)
TEST_DATA_DIR = base_test_case.test_data_dir
OUTPUT_DATA_DIR = base_test_case.output_data_dir
from app.utils.pymupdf_tools import get_pages_from_range

input_pdf = TEST_DATA_DIR / "1715339805571.pdf"


class GetPagesFromRangeTestCase(unittest.TestCase):
    """
    测试 get_pages_from_range 函数的各种输入条件
    """

    def setUp(self):
        """设置测试环境"""
        # 使用指定的测试PDF文件
        self.test_pdf_path = str(input_pdf)
        # 打开文档用于测试
        self.test_doc = fitz.open(self.test_pdf_path)

    def tearDown(self):
        """清理测试环境"""
        self.test_doc.close()

    def test_with_document_and_none_range(self):
        """测试传入fitz.Document对象且page_range为None的情况"""
        pages = get_pages_from_range(self.test_doc, None)
        self.assertEqual(len(pages), self.test_doc.page_count)
        # 检查返回的是页面对象
        for page in pages:
            self.assertIsInstance(page, fitz.Page)

    def test_with_document_and_tuple_range(self):
        """测试传入fitz.Document对象且page_range为tuple的情况"""
        # 正常范围 (限制在有效页面范围内)
        end_page = min(3, self.test_doc.page_count - 1)
        if end_page >= 1:
            pages = get_pages_from_range(self.test_doc, (1, end_page))
            self.assertEqual(len(pages), end_page)
            for i, page in enumerate(pages):
                self.assertEqual(page.number, i + 1)

    def test_with_document_and_list_range(self):
        """测试传入fitz.Document对象且page_range为list的情况"""
        if self.test_doc.page_count >= 3:
            pages = get_pages_from_range(self.test_doc, [0, 1, 2])
            self.assertEqual(len(pages), 3)
            expected_page_numbers = [0, 1, 2]
            for i, page in enumerate(pages):
                self.assertEqual(page.number, expected_page_numbers[i])

    def test_with_document_and_invalid_range(self):
        """测试传入fitz.Document对象且page_range为无效类型的情况"""
        pages = get_pages_from_range(self.test_doc, "invalid")
        # 应该返回所有页面
        self.assertEqual(len(pages), self.test_doc.page_count)

    def test_with_document_and_out_of_range_tuple(self):
        """测试传入fitz.Document对象且page_range元组超出范围的情况"""
        # 起始位置为负数
        pages = get_pages_from_range(self.test_doc, (-2, min(3, self.test_doc.page_count - 1)))
        self.assertGreater(len(pages), 0)

        # 结束位置超出范围
        pages = get_pages_from_range(self.test_doc, (min(2, self.test_doc.page_count - 1), 10))
        self.assertGreaterEqual(len(pages), 1)

    def test_with_document_and_out_of_range_list(self):
        """测试传入fitz.Document对象且page_range列表包含超出范围索引的情况"""
        pages = get_pages_from_range(self.test_doc, [0, 1, 100, -1, 2])
        # 根据get_pages_from_range函数的实现，只有有效的索引才会被添加到结果中
        # 有效索引判断条件为: 0 <= i < len(doc)
        valid_count = 0
        for i in [0, 1, 100, -1, 2]:
            if 0 <= i < self.test_doc.page_count:
                valid_count += 1
        self.assertEqual(len(pages), valid_count)

    # def test_with_page_object(self):
    #     """测试传入fitz.Page对象的情况"""
    #     if self.test_doc.page_count > 0:
    #         page = self.test_doc[0]  # 第1页
    #         pages = get_pages_from_range(page)
    #         self.assertEqual(len(pages), 1)
    #         self.assertEqual(pages[0].number, 0)
    #
    # def test_with_numpy_array(self):
    #     """测试传入numpy数组的情况"""
    #     arr = np.zeros((100, 100, 3), dtype=np.uint8)
    #     pages = get_pages_from_range(arr)
    #     self.assertEqual(len(pages), 0)  # numpy数组应该返回空列表

    def test_with_file_path_and_none_range(self):
        """测试传入文件路径且page_range为None的情况"""
        pages = get_pages_from_range(self.test_pdf_path, None)
        self.assertIsInstance(pages, list)

    def test_with_file_path_and_tuple_range(self):
        """测试传入文件路径且page_range为tuple的情况"""
        pages = get_pages_from_range(self.test_pdf_path, (0, min(2, self.test_doc.page_count - 1)))
        self.assertIsInstance(pages, list)

    def test_with_file_path_and_list_range(self):
        """测试传入文件路径且page_range为list的情况"""
        if self.test_doc.page_count >= 2:
            pages = get_pages_from_range(self.test_pdf_path, [0, 1])
            self.assertIsInstance(pages, list)

    def test_with_invalid_file_path(self):
        """测试传入无效文件路径的情况"""
        with self.assertRaises(Exception):
            get_pages_from_range("/invalid/path/to/file.pdf", (0, 1))

    # def test_with_invalid_source_type(self):
    #     """测试传入不支持的source类型的情况"""
    #     pages = get_pages_from_range(123)  # 整数类型
    #     self.assertEqual(len(pages), 0)

    def test_empty_document(self):
        """测试空文档的情况"""
        # 创建一个空的PDF文档
        empty_doc = fitz.open()
        pages = get_pages_from_range(empty_doc)
        self.assertEqual(len(pages), 0)
        empty_doc.close()

    def test_single_page_document(self):
        """测试单页文档的情况"""
        # 创建单页PDF文档
        single_page_doc = fitz.open()
        single_page_doc.new_page()
        pages = get_pages_from_range(single_page_doc)
        self.assertEqual(len(pages), 1)
        single_page_doc.close()


if __name__ == '__main__':
    unittest.main()
